﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Silvermoon.Controls;
using Passwords.Biz;
using Passwords.Utils;
using System.Drawing;
using Silvermoon.UI;
using Silvermoon.Animations;
using Silvermoon.Windows;
using Silvermoon.OpenGL;
using Silvermoon.Navigation;

namespace Passwords.Pages
{
    public class PasswordPicker : ItemPickerPage
    {
        private static readonly PasswordType[] types = new PasswordType[] { PasswordType.Numeric, PasswordType.Alpha, PasswordType.Alphanumeric, PasswordType.Complex };

        const int max = 130;
        const int min = 2;
        private TextBox passwordBox;
        private Slider strengthSlider;
        private DropDownBox dropDown;
        private bool focus;


        public PasswordPicker()
            : base()
        {
            SetTransition(300, TransitionMask.Fade | TransitionMask.Zoom, TransitionMask.Fade | TransitionMask.Explode);
            Title = "EDIT PASSWORD";
            ScrollStackPanel stack = new ScrollStackPanel { Margin = new Margin(20, 0, 20, 0) };
            passwordBox = new TextBox { Margin = new Margin(0, 10, 0, 0), AutoHeight = false, Height = 64 };
            Label l1 = new Label("Strength") { Margin = new Margin(0, 20, 0, 0) };
            strengthSlider = new Slider { Margin = new Margin(0, 2, 0, 0), Height = 48, Readonly = true, Minimum = min, Maximum = max, Value = 30 };
            Panel levels = new Panel { Margin = new Margin(0, 0, 0, 0), Height = 32 };
            levels.Controls.Add(
                new Label("weak") { FontScale = 0.5f, AutoSize = false, Alignment = Alignment.Near, Margin = Margin.Zero, LineAlignment = Alignment.Near },
                new Label("medium") { FontScale = 0.5f, AutoSize = false, Alignment = Alignment.Center, Margin = Margin.Zero, LineAlignment = Alignment.Near },
                new Label("strong") { FontScale = 0.5f, AutoSize = false, Alignment = Alignment.Far, Margin = Margin.Zero, LineAlignment = Alignment.Near });

            Label l2 = new Label("Type") { Margin = new Margin(0, 10, 0, 0) };
            dropDown = new DropDownBox { Margin = new Margin(0, 10, 0, 0), ItemHeight = 64 };
            dropDown.GetVirtualItem += new EventHandler<ItemEventArgs>(dropDown_GetVirtualItem);

            Button btn = new Button { Margin = new Margin(0, 20, 0, 0), Height = 64, Content = "Generate" };
            btn.Tap += new EventHandler<TapEventArgs>(OnGeneratePassword);
            stack.Controls.Add(passwordBox, l1, strengthSlider, levels, l2, dropDown, btn);
            Controls.Add(stack);

            passwordBox.TextChanged += new EventHandler(OnPasswordTextChanged);
            dropDown.ItemsSource = types;
            dropDown.SelectedItemIndex = 1;

        }

        public PasswordPicker(bool focus)
            : this()
        {
            this.focus = focus;
        }

        public static PropertyAccessor<PasswordPicker, Color> StrengthColorProperty = PropertyAccessor.Register<PasswordPicker, Color>("StrengthColor",
            c => c.StrengthColor, (c, v) => c.StrengthColor = v);

        public Color StrengthColor
        {
            get { return strengthSlider.FillColor; }
            set
            {
                if (StrengthColor != value)
                {
                    strengthSlider.FillColor = value;
                }
            }
        }

        void dropDown_GetVirtualItem(object sender, ItemEventArgs e)
        {
            PasswordType type = (PasswordType)e.Value;
            TextItem item = new TextItem(type.ToString());
            e.Item = item;
        }

        void OnGeneratePassword(object sender, TapEventArgs e)
        {
            PasswordType type = types[dropDown.SelectedItemIndex];
            LengthPicker page = new LengthPicker(type) { Item = this.PasswordItem };
            this.NavigateTo(page);
        }


        protected override void OnShown()
        {
            base.OnShown();
            //     if (focus) passwordBox.SetFocus();
        }

        void OnPasswordTextChanged(object sender, EventArgs e)
        {
            int strength = Math.Max(min + 1, Math.Min(max, PasswordUtility.GetStrength(passwordBox.Text)));

            strengthSlider.Value = strength;

            SetStrengthColor(strength);
            IsSaveEnabled = true;

        }

        private void SetStrengthColor(int strength)
        {
            PasswordStrengthLevel level = PasswordUtility.GetLevelFromValue(strength);
            ColorTransition ct = new ColorTransition(100, null, GetColorFrom(level));
            StrengthColorProperty.Animate(this, ct);
        }

        private Color GetColorFrom(PasswordStrengthLevel level)
        {
            switch (level)
            {
                case PasswordStrengthLevel.Weak: return PhoneColors.Red;
                case PasswordStrengthLevel.Medium: return PhoneColors.Yellow;
                case PasswordStrengthLevel.Good: return PhoneColors.Green;
                default: return PhoneColors.Lime;
            }
        }

        protected override void OnOK(object sender, CommandEventArgs e)
        {
            this.PasswordItem.Value = passwordBox.Text;
            base.OnOK(sender, e);
        }

        protected override void OnPasswordItemChanged(PasswordItem item)
        {
            string value = item != null ? item.Value : string.Empty;
            passwordBox.Text = value;
            base.OnPasswordItemChanged(item);
        }

        private class Bag
        {
            public PasswordItem Item;
            public int index;
        }

        public override void OnLoadViewState(object viewState)
        {
            Bag bag = viewState as Bag;
            if (bag != null)
            {
                PasswordItem = bag.Item;
                dropDown.SelectedItemIndex = bag.index;
            }
        }

        public override object OnSaveViewState()
        {
            Bag bag = new Bag { Item = this.PasswordItem, index = dropDown.SelectedItemIndex };
            return bag;
        }

    }
}
